package cn.foxtech.cloud.repository.controller;

import cn.craccd.mongoHelper.utils.CriteriaWrapper;
import cn.foxtech.cloud.core.domain.AjaxResult;
import cn.foxtech.cloud.core.exception.ServiceException;
import cn.foxtech.cloud.repo.comp.haas.constants.ConstantRepoCompHaas;
import cn.foxtech.cloud.repo.comp.haas.constants.ConstantRepoCompHaasVersion;
import cn.foxtech.cloud.repo.comp.haas.entity.RepoCompHaasEntity;
import cn.foxtech.cloud.repo.comp.haas.entity.RepoCompHaasVersionEntity;
import cn.foxtech.cloud.repo.comp.haas.service.RepoCompHaasService;
import cn.foxtech.cloud.repo.comp.haas.service.RepoCompHaasVersionService;
import cn.foxtech.cloud.repo.group.service.RepoGroupService;
import cn.foxtech.common.utils.bean.BeanMapUtils;
import cn.foxtech.common.utils.json.JsonUtils;
import cn.foxtech.common.utils.method.MethodUtils;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/repository/component/haas/version")
public class RepoCompHaasVersionController {
    @Autowired
    private RepoCompHaasService haasService;

    @Autowired
    private RepoCompHaasVersionService versionService;

    @Autowired
    private RepoGroupService groupService;

    @RequiresPermissions("monitor:repo:query")
    @PostMapping("page")
    public AjaxResult getVersionPage(@RequestBody Map<String, Object> body) {
        return this.getList(body, true);
    }

    @RequiresPermissions("monitor:repo:query")
    @PostMapping("entities")
    public AjaxResult getVersionList(@RequestBody Map<String, Object> body) {
        return this.getList(body, false);
    }

    public AjaxResult getList(Map<String, Object> body, boolean isPage) {
        try {
            String username = SecurityUtils.getUsername();
            if (MethodUtils.hasEmpty(username)) {
                throw new ServiceException("获得登录用户信息失败!");
            }

            String haasId = (String) body.get(ConstantRepoCompHaasVersion.field_haas_id);

            if (MethodUtils.hasEmpty(haasId)) {
                throw new ServiceException("body参数缺失: haasId");
            }

            // 查询实体
            RepoCompHaasEntity haasEntity = this.haasService.queryEntity(haasId);
            if (haasEntity == null) {
                throw new ServiceException("找不到对应的实体");
            }

            // 当前用户所属的组信息
            Set<String> groupIds = this.groupService.queryGroupIds(username);

            // 检查权限
            if (!username.equals(haasEntity.getOwnerId()) // 作者有权限
                    && !groupIds.contains(haasEntity.getGroupId()) // 群组成员有权限
                    && !username.equals("admin")// 管理员有权限
            ) {
                throw new ServiceException("只有 admin / owner / group member 有权限查看");
            }

            // 构造过滤器
            CriteriaWrapper criteriaWrapper = this.versionService.buildWrapper(body);

            if (isPage) {
                // 查询主数据
                Map<String, Object> data = this.versionService.queryPageList(criteriaWrapper, body);

                // 扩展信息
                Map<String, Object> result = this.extend(data, haasEntity);

                return AjaxResult.success(result);
            } else {
                // 查询主数据
                List<RepoCompHaasVersionEntity> entityList = this.versionService.queryEntityList(criteriaWrapper);

                // 扩展信息
                List<Map<String, Object>> result = this.extend(entityList, haasEntity);

                return AjaxResult.success(result);
            }


        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    private Map<String, Object> extend(Map<String, Object> data, RepoCompHaasEntity modelEntity) throws IOException {
        // 扩展信息
        String json = JsonUtils.buildJson(data);
        Map<String, Object> result = JsonUtils.buildObject(json, Map.class);
        List<Map<String, Object>> list = (List<Map<String, Object>>) result.get("list");
        for (Map<String, Object> map : list) {
            map.put(ConstantRepoCompHaas.field_hard_manufacturer, modelEntity.getHardManufacturer());
            map.put(ConstantRepoCompHaas.field_hard_device_type, modelEntity.getHardDeviceType());
            map.put(ConstantRepoCompHaas.field_soft_manufacturer, modelEntity.getSoftManufacturer());
            map.put(ConstantRepoCompHaas.field_soft_device_type, modelEntity.getSoftDeviceType());

            String uri = this.versionService.getUri(modelEntity, (String) map.get(ConstantRepoCompHaasVersion.field_filename));
            map.put(ConstantRepoCompHaasVersion.field_uri, uri);
        }

        return result;
    }

    private List<Map<String, Object>> extend(List<RepoCompHaasVersionEntity> list, RepoCompHaasEntity modelEntity) throws IOException {
        List<Map<String, Object>> resultList = new ArrayList<>();

        for (RepoCompHaasVersionEntity entity : list) {
            Map<String, Object> map = BeanMapUtils.objectToMap(entity);
            map.put(ConstantRepoCompHaas.field_hard_manufacturer, modelEntity.getHardManufacturer());
            map.put(ConstantRepoCompHaas.field_hard_device_type, modelEntity.getHardDeviceType());
            map.put(ConstantRepoCompHaas.field_soft_manufacturer, modelEntity.getSoftManufacturer());
            map.put(ConstantRepoCompHaas.field_soft_device_type, modelEntity.getSoftDeviceType());
            map.put(ConstantRepoCompHaas.field_group_id, modelEntity.getGroupId());
            map.put(ConstantRepoCompHaas.field_group_name, modelEntity.getGroupName());

            String uri = this.versionService.getUri(modelEntity, entity.getFileName());
            map.put(ConstantRepoCompHaasVersion.field_uri, uri);
            resultList.add(map);
        }

        return resultList;
    }

    @PutMapping("entity")
    public AjaxResult update(@RequestBody Map<String, Object> body) {
        try {
            String userName = SecurityUtils.getUsername();
            if (MethodUtils.hasEmpty(userName)) {
                throw new ServiceException("获得登录用户信息失败!");
            }

            // 查询数据
            this.versionService.updateEntity(userName, body);

            return AjaxResult.success();

        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @DeleteMapping("entity")
    public AjaxResult delete(String id) {
        try {
            String userName = SecurityUtils.getUsername();
            if (MethodUtils.hasEmpty(userName)) {
                throw new ServiceException("获得登录用户信息失败!");
            }

            this.versionService.delete(userName, id);

            return AjaxResult.success();

        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }
}
